<?php

namespace CHOMP\SGIBundle\Services;
use Symfony\Component\HttpFoundation\Session\Session;
use Doctrine\ORM\EntityManager;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\DependencyInjection\Container;
use CHOMP\SGIBundle\Entity\Rol;
use CHOMP\SGIBundle\Entity\Usuario;
use CHOMP\SGIBundle\Entity\RolRepository;
use Doctrine\Common\Collections\ArrayCollection;
use CHOMP\SGIBundle\Exception\DeletedUserException;
use CHOMP\SGIBundle\Exception\ExpiredPasswordException;
use CHOMP\SGIBundle\Exception\EmptyValueException;
use CHOMP\SGIBundle\Exception\FirstTimeLoginException;
use CHOMP\SGIBundle\Exception\InactiveUserException;
use CHOMP\SGIBundle\Exception\IncorrectPasswordException;
use CHOMP\SGIBundle\Exception\InexistentUserException;
use CHOMP\SGIBundle\Exception\InexistentEmpresaException;
use CHOMP\SGIBundle\Exception\LockedUserException;
use CHOMP\SGIBundle\Exception\PermissionDeniedException;
use CHOMP\SGIBundle\Exception\RolNotFoundException;
use CHOMP\SGIBundle\Exception\LDAPErrorException;
use CHOMP\SGIBundle\Exception\LDAPPasswordNotChangedException;
//use CHOMP\SGIBundle\Services\Menu;
use Knp\Menu\FactoryInterface;
use Symfony\Component\HttpFoundation\Request;
//use CHOMP\SGIBundle\Services\ADUsuarios;


class SessionManager 
{
    
    /** 
     * 
     * @var Container
     */
    public $container;
    
    /**
     * @var EntityManager
     */
    public $em;
    
    /**
     * @var Session
     */
    public $session;

    /** 
     * 
     * @var array
     */
    public $permissionsMap;

     /** 
     * 
     * @var FactoryInterface
     */
    public $factory;


    /**
     * @param FactoryInterface $factory
     */
    public function __construct(Container $container, FactoryInterface $factory){              
        $this->container = $container;
        $this->factory = $factory;
        $this->em = $container->get('doctrine.orm.entity_manager');
        $this->session = $container->get('session');
        $this->permissionsMap = new ArrayCollection();
        $this->setPermisosMap();
        /*$this->adUsuariosService = $adUsuariosService;*/
    }


    public function checkIfUserIsLoggedInLDAP(){
        $nombreUsuario = '';
        try{
            if (isset( $_SERVER['REMOTE_USER'] ) )
                $nombreUsuarioConArroba = $_SERVER['REMOTE_USER'];
            else{
                return false;
            }
        }catch( ContextErrorException $e){
        }catch(Exception $e){
        }

        if ($nombreUsuarioConArroba != null && $nombreUsuarioConArroba != '')
           return true;
        return false;
    }


    public function splitUsuario(){
        $nombreUsuarioConArroba = $_SERVER['REMOTE_USER'];
        $posArroba = strpos($nombreUsuarioConArroba, '@');
        return (substr($nombreUsuarioConArroba, 0, $posArroba));
    }


    public function getLdapUsers(){
        $command = "wget -qO- http://www.sgicaece.com/consulta_usuarios.php";
        exec ("$command > /dev/null &" );
	sleep(2);
    }

    /**
     * @throws ExpiredPasswordException
     * @throws DeletedUserException
     * @throws FirstTimeLoginException
     * @throws InactiveUserException
     * @throws IncorrectPasswordException
     * @throws InexistentUserException
     * @throws InexistentEmpresaException
     * @throws LockedUserException
     * @throws RolNotFoundException
     * @throws Exception
     */
    public function startSession(){
        $this->session->start();
        $this->setSession('permisos','');
        $this->setSession('userName', 'false');
        $this->setSession('empresa', '');
        $this->setSession('esAdmin', '');
        $this->setSession('rolId', '');
        $this->setSession('userId', '');

        $this->getLdapUsers();
 
        $isLoggedInLDAP = $this->checkIfUserIsLoggedInLDAP();

        if ($isLoggedInLDAP){
            $nomUsuarioSplitted = $this->splitUsuario();
            $this->login($nomUsuarioSplitted, '', $isLoggedInLDAP);
        }
    }


    public function clearSession(){
        $this->session->clear();
        $this->session->getFlashBag()->clear();
    }

    public function closeSession(){
        $this->clearSession();
        $this->startSession();
    }

    /**
     * Setea un parametro en la sesion
     * @param string $attr
     * @param string $value
     * @return mixed
     */
    public function setSession($attr, $value){
        $this->session->set($attr, $value);
    }

   /**
     * Devuelve un valor de la sesion
     * @param string $attr
     * @return mixed
     */
    public function getSession($attr){
        return $this->session->get($attr);
    }
	    	
	/**
     * 
     * @throws PermissionDeniedException
     * @throws InexistentUserException
     * @throws InactiveUserException
     * @throws LockedUserException  
     * @throws DeletedUserException  
     * @throws Exception
     * @return boolean
     */
	public function userIsLogged(){
		if ( ($this->session->has('userName')) && ($this->session->get('userName')!='false') ) {
            try{
                $isActive = $this->userIsActive();	
            }catch(PermissionDeniedException $e){
            	$this->addFlash('msgError','No tiene permisos para ver esta pagina.');
            	$this->closeSession();
                throw $e;
            }catch(InexistentUserException $e1){
            	$this->addFlash('msgError','El usuario no existe.');
            	$this->closeSession();
                throw $e1;
            }catch(InexistentEmpresaException $e1){
            	$this->addFlash('msgError','Su empresa ya no pertenece al sistema. Comuniquese con su administrador.');
            	$this->closeSession();
                throw $e1;
            }catch(InactiveUserException $e2){
            	$this->addFlash('msgError','El usuario está inactivo.');
            	$this->closeSession();
                throw $e2;
            }catch(LockedUserException $e3){
            	$this->addFlash('msgError','Usuario lockeado.');
            	$this->closeSession();
                throw $e3;
            }catch(DeletedUserException $e4){
            	$this->addFlash('msgError','El usuario fue eliminado.');
            	$this->closeSession();
                throw $e4;
            }catch(Exception $e5){
            	$this->addFlash('msgError','Error');
            	$this->closeSession();
                throw $e5;
            }
            if($isActive){
                return true;
            }else{
                $this->closeSession();
                return false;
            }
        }else{
		  	/* $this->addFlash('msgError','El usuario no esta logueado.'); */
        	return false;
        }
	}

    /**
     * 
     * @throws PermissionDeniedException
     * @throws InexistentUserException
     * @throws InactiveUserException
     * @throws LockedUserException  
     * @throws DeletedUserException   
     * @throws Exception
     * @return boolean
     */
    public function userIsActive(){
        try {
            $usuario = $this->getCurrentUser();   
            $estado = $usuario->getEstado();
            switch($estado){
                case '0':
                    $this->setUser($usuario);
                break;
                case '1':
                    throw new InactiveUserException();
				break;
                case '2':
                    throw new LockedUserException();
				break;
                case '3':
                    throw new DeletedUserException();
                break;
                case '4':
                    throw new LockedUserException();
                break;
            }
			
			if($usuario->getBorrado()){
				return false;
			}  

			if($usuario->getEmpresa()->getBorrado()){
				return false;
			}  

        } catch (PermissionDeniedException $e) {
            throw  $e;
        } catch (InexistentUserException $e1) {
            throw  $e1;
        }
        return true;
    }


	/**
    * @return boolean
    */
	public function userIsSuperAdmin(){
		if ( ($this->session->has('esAdmin')) && ($this->session->get('esAdmin')=='SI') ) 
			return true;
		return false;
	}

	/**
	* @param string $routeRequested
	* @return boolean
	*/
	public function pageHasMenu($routeRequested){
		if ( ($routeRequested != 'chompsgi_homepage') && ($routeRequested != 'chompsgi_login') && ($routeRequested != 'chompsgi_restClave') )
			return true;
		return false;
	}

	/**
	* @param string $routeRequested
	* @return boolean
	*/
	public function pageHasLeftMenu($routeRequested){
		//to do
		return true;
	}
	
 /**
     * 
     * @param string $username
     * @param string $pass
     * @throws LDAPErrorException
     * @throws Exception
     * @return boolean
     */

    public function loginLDAP($username, $pass){

        // variables de autenticacion y LDAP
        $ldap["user"]              = $username;
        $ldap["pass"]              = $pass;
        // Toma parametros de src/CHOMP/SGIBundle/Resources/caecesgi.yml
        $ldap["host"]              = $this->container->getParameter('ldap_host'); // nombre del host o servidor
        $ldap["port"]              = $this->container->getParameter('ldap_port'); // puerto del LDAP en el servidor
        $ldap["dn"]                = "cn=$username,ou=Usuarios"; // modificar respecto a los valores del LDAP
        $ldap["base"]              = $this->container->getParameter('ldap_base');

        $ldap["conn"] = ldap_connect($ldap["host"],$ldap["port"]);
        // match de usuario y password
	return @ldap_bind($ldap["conn"], $ldap["dn"] . "," . $ldap["base"], $pass);
    }

    /**
     * Loguea usuario
     * @param string $username
     * @param string $pass
     * @throws ExpiredPasswordException
     * @throws DeletedUserException
     * @throws FirstTimeLoginException
     * @throws InactiveUserException
     * @throws IncorrectPasswordException
     * @throws InexistentUserException
     * @throws InexistentEmpresaException
     * @throws LockedUserException
     * @throws RolNotFoundException
     * @throws Exception
     * @return boolean
     */

    public function login($username, $pass, $isLdap){

        $usuario = $this ->em->getRepository('CHOMPSGIBundle:Usuario')->findOneBy(array('login' => $username));
        if ($usuario == null or $usuario->getBorrado())
            throw new InexistentUserException();
    	// Validacion con ldap
    	// variable ldap_status global en src/CHOMP/SGIBundle/Resources/caecesgi.yml 
        /*
        $ldap = $this->container->getParameter('ldap_status');
    	if ( $ldap == 'yes'){
            if ( !($this->loginLDAP ($username, $pass))) { 
    			throw new LDAPErrorException();
    		}
        } else {
			
    	}
        */
        //check Empresa
        if($usuario->getEmpresa()->getBorrado()){
            throw new InexistentEmpresaException();
        }

        if (!$isLdap){
            //check password
            $encrypted = $this->encryptIt( $pass );
            $con = $username .'///'. $encrypted;
            $passwd = $usuario->getPassword();
            if ($con != $passwd)
                throw new IncorrectPasswordException();
        
            $this->setUser($usuario);
            if ($usuario->getPrimerIngreso()){
                $this->setSession('firstPass', 'si');
                throw new FirstTimeLoginException();
            }

            //check pass expiration
            $fechaExp = $usuario->getPasswordExpiryDate();
            $now = new \DateTime();    
            if($fechaExp <= $now)
                throw new ExpiredPasswordException();

        }


        //check user estado
        $estado = $usuario->getEstado();
        switch($estado){
            case '0':
            	$this->setUser($usuario);
                return true;
            break;
            case '1':
                throw new InactiveUserException();
            break;
            case '2':
                throw new LockedUserException();
            break;
            case '3':
                throw new DeletedUserException();
            break;
            case '4':
               throw new ExpiredPasswordException();
            break;
        }

    }

    /**
     * Setea usuario en la sesion
     * @param Usuario
     */
    private function setUser($usuario){
    	$this->setSession('userName', $usuario->getLogin());
        $this->setSession('userId', $usuario->getId());
        $this->setSession('empresa', $usuario->getEmpresa()->getId());
        $this->setSession('rolId', $usuario->getRol()->getId());
        $this->setSession('esAdmin', 'NO');
        $this->setPermisos(); 
    }

    /**
     * 
     * @param string $username
     * @param string $pass
     * @throws LDAPErrorConnection 
     * @throws LDAPErrorException
     * @throws Exception
     * @return boolean
     */

    public function changePasswordLDAP($username, $pass){

        // Toma parametros de src/CHOMP/SGIBundle/Resources/caecesgi.yml
        // variables de autenticacion y LDAP
        $ldap["user"]              = $username;
        $ldap["pass"]              = $pass;
		$ldap["admin"]		   	   = $this->container->getParameter('ldap_admin');
		$ldap["adminPass"]	   	   = $this->container->getParameter('ldap_admin_pass');
        $ldap["host"]              = $this->container->getParameter('ldap_host'); // nombre del host o servidor
        $ldap["port"]              = $this->container->getParameter('ldap_port'); // puerto del LDAP en el servidor
        $ldap["dn"]                = "cn=$username,ou=Usuarios"; // modificar respecto a los valores del LDAP
        $ldap["base"]              = $this->container->getParameter('ldap_base');

        // Conexion con LDAP
        $ldap["conn"] = ldap_connect($ldap["host"],$ldap["port"]);
	//	or die( throw new LDAPErrorConnection());

       	$dnUser = $ldap["dn"] . "," . $ldap["base"];
        $dnAdmin = "cn=" . $ldap["admin"] . "," . $ldap["base"]; 
	$newPass = array('userpassword' => "{MD5}".base64_encode(pack("H*",md5($pass))));

	if ( !(ldap_bind($ldap["conn"], $dnAdmin, $ldap["adminPass"])))
		 throw new LDAPErrorException();

	return @ldap_mod_replace($ldap["conn"], $dnUser, $newPass);
    }


    /**
     * Cambia password
     * @param string $username
     * @param string $pass
     * @throws InexistentUserException
     * @throws PermissionDeniedException
     * @throws LDAPPasswordChangedException
     * @throws LDAPPasswordNotChangedException
     */

    public function changePassword($username, $pass){
        try{
        	$usuario=$this->getCurrentUser();
        }catch(InexistentUserException $e){
        	throw new InexistentUserException();
        }

		if ($usuario->getLogin() != $username){
			throw new PermissionDeniedException();
		}

        $fechaNueva = new \DateTime('tomorrow + 180 day');
        
        $encrypted = $this->encryptIt( $pass );
        $con = $username .'///'. $encrypted;
        
        $usuario->setPasswordExpiryDate($fechaNueva);
	
    	$ldap = $this->container->getParameter('ldap_status');
        /*if ( $ldap == 'yes'){
    		//Modifica pass de LDAP
    		if (!($this->changePasswordLDAP($username, $pass)))
    		      throw new LDAPPasswordNotChangedException();
    	}else{*/
    		//Si no esta seteado LDAP cambia pass en base de datos.
            $usuario->setPassword($con);
    	//}
        $usuario->setPrimerIngreso(false); 
    	$this->setSession('firstPass', 'no');

        $this->em->persist($usuario);
        $this->em->flush();
    }


    public function forgotPasswordLDAP($username){
    
    }


     /**
     * Devuelve el usuario username
     * @param string $username
     * @throws EmptyValueException
     * @throws InexistentUserException
     * @return Usuario
     */
    public function forgotPassword($username){
    	//check empty field
    	if ($username == '')  
    		throw new EmptyValueException(); 
    	
    	//get user
		$usuario = $this->em->getRepository('CHOMPSGIBundle:Usuario')->findOneBy(array('login' => $username));
		
		//check user null
		if ($usuario == null)
			throw new InexistentUserException();

		return $usuario;
    }

    /**
    * Agrega un mensaje de tipo msgType a la siguiente response.
    * msgType validos: msgOk, msgInfo, msgWarn, msgError.
    * @param string $msgType
    * @param string $msg
    */
    public function addFlash($msgType, $msg){
        $this->session->getFlashBag()->add($msgType, $msg);
    }

    /**
     * Busca un permiso en los permisos del usuario logueado
     * @param string
     * @throws PermissionDeniedException
     * @throws InexistentUserException
     * @throws InactiveUserException
     * @throws LockedUserException  
     * @throws DeletedUserException  
     * @throws Exception
     * @return boolean
     */
    public function isGranted($permisoString){
        if ( $this->userIsLogged() == false)
            return false;
        if ( $this->userIsSuperAdmin() )
        	return true;

    	switch ( $permisoString ){
    		case 'CREAR_INCIDENTE_ALL':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('CREAR_INCIDENTE_ALL') )
                    return true;
                break;
            case 'EDITAR_CUENTAANALITICA': 
            	if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('EDITAR_CUENTAANALITICA') )
                    return true;
                break;  
            case 'EDITAR_CONFIGURACION':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('EDITAR_CONFIGURACION') )
                    return true;
                break;
            case 'EDITAR_EMPRESA':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('EDITAR_EMPRESA') )
                    return true;
                break;
            case 'EDITAR_GRUPOSOPORTE':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('EDITAR_GRUPOSOPORTE') )
                    return true;
                break;
            case 'EDITAR_INCIDENTE_ALL':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') )
                    return true;
                break;
            case 'EDITAR_INCIDENTE_COMENTARIO':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('EDITAR_INCIDENTE_COMENTARIO') )
                    return true;
                break;
            case 'EDITAR_INCIDENTE_CUENTAANALITICA':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('EDITAR_INCIDENTE_CUENTAANALITICA') )
                    return true;
                break;
            case 'EDITAR_INCIDENTE_ESTADO':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('EDITAR_INCIDENTE_ESTADO') )
                    return true;
                break;     
            case 'EDITAR_INCIDENTE_ESTADONOCERRADO':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('EDITAR_INCIDENTE_ESTADONOCERRADO') )
                    return true;
                break;
            case 'EDITAR_INCIDENTE_GRUPOSOPORTE':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('EDITAR_INCIDENTE_GRUPOSOPORTE') )
                    return true;
                break;
            case 'EDITAR_INCIDENTE_PRIORIDAD':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('EDITAR_INCIDENTE_PRIORIDAD') )
                    return true;
                break;      
            case 'EDITAR_INCIDENTE_RESPONSABLESOPORTE':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('EDITAR_INCIDENTE_RESPONSABLESOPORTE') )
                    return true;
                break; 
            case 'EDITAR_INCIDENTE_RESPONSABLECLIENTE':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('EDITAR_INCIDENTE_RESPONSABLECLIENTE') )
                    return true;
                break; 
            case 'EDITAR_PRIORIDAD':
            	if ( $this->permisosHaveSubstring('EDITAR_PRIORIDAD') )
                    return true;
                break;  
            case 'EDITAR_REPORTES':
            	if ( $this->permisosHaveSubstring('EDITAR_REPORTES') )
                    return true;
                break; 
            case 'EDITAR_SEGURIDAD':
            	if ( $this->permisosHaveSubstring('EDITAR_SEGURIDAD') )
                    return true;
                break;  
            case 'EDITAR_TIMESHEET':
            	if ( $this->permisosHaveSubstring('EDITAR_TIMESHEET') )
                    return true;
                break;  
            case 'EDITAR_USUARIO':
            	if ( $this->permisosHaveSubstring('EDITAR_USUARIO') )
                    return true;
                break;  
            case 'EDITAR_WORKFLOW':
            	if ( $this->permisosHaveSubstring('EDITAR_WORKFLOW') )
                    return true;
                break; 
    		case 'VER_CONFIGURACION':
    			if ( $this->permisosHaveSubstring('INCIDENTE') || $this->permisosHaveSubstring('EMPRESA')  || $this->permisosHaveSubstring('CUENTAANALITICA') )
    				return true;
    			return false;
    			break;
    		case 'VER_CUENTAANALITICA':
    			if ( $this->permisosHaveSubstring('CUENTAANALITICA') )
    				return true;
    			break;
    		case 'VER_EMPRESA':
    			if ( $this->permisosHaveSubstring('EMPRESA') )
    				return true;
    			break;
    		case 'VER_GRUPOSOPORTE':
    			if ( $this->permisosHaveSubstring('GRUPOSOPORTE') )
    				return true;
    			break;
            case 'VER_INICIO':
    			return ( $this->userIsLogged() );
    			break;
            case 'VER_INCIDENTE_ALL':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('VER_INCIDENTE_ALL') )
                    return true;
                break;
            case 'VER_INCIDENTE_COMENTARIO':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('VER_INCIDENTE_COMENTARIO') )
                    return true;
                break;
            case 'VER_INCIDENTE_CUENTANALITICA':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('VER_INCIDENTE_CUENTAANALITICA') )
                    return true;
                break;
            case 'VER_INCIDENTE_ESTADO':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('VER_INCIDENTE_ESTADO') )
                    return true;
                break;     
            case 'VER_INCIDENTE_ESTADONOCERRADO':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('VER_INCIDENTE_ESTADONOCERRADO') )
                    return true;
                break;
            case 'VER_INCIDENTE_GRUPOSOPORTE':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('VER_INCIDENTE_GRUPOSOPORTE') )
                    return true;
                break; 
            case 'VER_INCIDENTE_PRIORIDAD':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('VER_INCIDENTE_PRIORIDAD') )
                    return true;
                break;      
            case 'VER_INCIDENTE_RESPONSABLESOPORTE':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('VER_INCIDENTE_RESPONSABLESOPORTE') )
                    return true;
                break; 
            case 'VER_INCIDENTE_RESPONSABLECLIENTE':
                if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('VER_INCIDENTE_RESPONSABLECLIENTE') )
                    return true;
                break;
    		case 'VER_INCIDENTES':
    			if ( $this->permisosHaveSubstring('EDITAR_INCIDENTE_ALL') || $this->permisosHaveSubstring('INCIDENTE') )
    				return true;
    			return false;
    			break;
    		case 'VER_PRIORIDAD':
    			if ( $this->permisosHaveSubstring('PRIORIDAD') )
    				return true;
    			return false;
    			break;
    		case 'VER_REPORTES':
    			if ( $this->permisosHaveSubstring('EDITAR_REPORTES') || $this->permisosHaveSubstring('REPORTES') )
    				return true;
    			return false;
    			break;
    		case 'VER_SEGURIDAD':
    			if ( $this->permisosHaveSubstring('EDITAR_SEGURIDAD') || $this->permisosHaveSubstring('SEGURIDAD') )
    				return true;
    			return false;
    			break;
    		case 'VER_TIMESHEET':
    			if ( $this->permisosHaveSubstring('EDITAR_TIMESHEET') || $this->permisosHaveSubstring('TIMESHEET') )
    				return true;
    			return false;    			
    		case 'VER_USUARIO':
    			if ( $this->permisosHaveSubstring('EDITAR_USUARIO') || $this->permisosHaveSubstring('USUARIO') )
    				return true;
    			return false;
    			break;
    		case 'VER_WORKFLOW':
    			if ( $this->permisosHaveSubstring('EDITAR_WORKFLOW') || $this->permisosHaveSubstring('WORKFLOW') )
    				return true;
    			return false;
    		default:
    			return false;

    	}
        
        
    }


    /**
    * Recibe un permiso y devuelve las empresas correspondientes
    * separadas por comas
    * @param string $permisoBuscado
    * @return string
    */
	public function getEmpresasFor($permisoBuscado){
		//if doesn't exist
			//return 0;
		//get current user permissions
    	$userRol = $this->getCurrentUser()->getRol();
    	$permisosArray = $this->getPermisos($userRol);

    	if (null == $permisosArray){
    		$this->setSession('debug', 'permisos are null' );
    		return false;
    	}

    	$empresasString = '0';
    	//look for $substring 
    	foreach($permisosArray as $permisoString)
		{
			if(strpos($permisoString, $permisoBuscado) !== false) 
			{
				//$substring found, permission exists, debug it
				$empresasString .= $this->getEmpresaIdInPermisoString($permisoString).',';
			}
		
		}
		if(strpos($empresasString, 'ALL') !== false) {
			$empresasString = 'ALL';
		}
		return $empresasString;

	}

    /**
    * @param string $substring
    * @return boolean
    */
    public function permisosHaveSubstring($substring){
    	//get current user permissions
    	$userRol = $this->getCurrentUser()->getRol();
    	$permisosArray = $this->getPermisos($userRol);

    	if (null == $permisosArray){
    		$this->setSession('debug', 'permisos are null' );
    		return false;
    	}

    	//look for $substring 
    	foreach($permisosArray as $permisoString)
		{
			if(strpos($permisoString, $substring) !== false) 
			{
				//$substring found, permission exists, debug it
				$this->setSession($substring, strpos($substring, $permisoString) );
				return true;
			}
		}
		return false;
    }

    /**
    * @param string $completePermisoString
    * @return string
    */
	public function getEmpresaIdInPermisoString($completePermisoString){
		$theEmpId = '';
		if(strpos($completePermisoString, 'EMP:') !== false) {
			$theEmpId = substr( $completePermisoString, ( strpos($completePermisoString, 'EMP:')+4 ) );
		}

	}


    /**
     * 
     * @throws PermissionDeniedException
     * @throws InexistentUserException
     * @throws Exception
     * @return Usuario
     */
    public function getCurrentUser(){
        $u = $this->session->get('userName');
        if( $u == 'false' )
            throw new PermissionDeniedException();

        $us= $this->em->getRepository('CHOMPSGIBundle:Usuario')->findOneBy(array('login' => $u));

        if ($us == null)
            throw new InexistentUserException();

        return $us;
    }

    /**
    *   Setea un mapa de permiso_string por id del permisoAutorizacion.
    *   Ej: 1 => "VER_INCIDENTES_ALL_EMP:4"
    */
    private function setPermisosMap(){
        $allPermAuts = $this ->em->getRepository('CHOMPSGIBundle:PermisoAutorizacion')->findAll();
        
        if (!$allPermAuts){
        	//to do: throw PermissionsNotLoadedException
        }
        
        foreach ($allPermAuts as $pa){
            $paId = $pa->getId();
            $permisoString = '';
            $permisoString.=$pa->getPermiso()->getDescripcion().'_';
            $permisoString.=$pa->getAutorizacion()->getObjeto().'_';
            $permisoString.=$pa->getAutorizacion()->getCampo().'_';
            $permisoString.='EMP:'.$pa->getAutorizacion()->getEmpresa();
            $permisoString = strtoupper($permisoString);
            $this->permissionsMap->set($paId, $permisoString);
            
        }
    }


    public function setPermisos(){
    	//get user rol
        $rol = $this->getCurrentUser()->getRol();
        if ($rol == null){
            $this->addFlash('msgError', 'Rol no encontrado en la sesión');
            //To do: throw RolNotFoundException
            return false;
        }

        //set es admin
        if ($rol->getNombre() == 'Administrador Root'){
            $this->setSession('esAdmin', 'SI');
        }else{
        	$this->setSession('esAdmin', 'NO');
        }
       
       	//for debuggin
		$this->setSession('nombreRol', $rol->getNombre());

        try{
        	//get permisos for this rol
            $arrayCollectionPermisos = $this->getPermisosStrings($rol->getPermisos());
            $permis = $arrayCollectionPermisos;
            if (count($permis) < 1){
                $permisosOneString = '';
            }else{
                $permisosOneString = implode(';', $permis);
            }

            //set permisos in session
            $this->setSession('permisos', $permisosOneString);
            return true;
        }catch(Exception $e){
            //To do: throw NoPermissionsFoundException;
            //return false;
            $this->addFlash('msgError', 'No se encontraron permisos.');
            return false;
        }
    }


    /**
     * 
     * @param \CHOMP\SGIBundle\Entity\Rol $rol
     * @return array
     */
    public function getPermisos($rol){
        if (null != $rol){
            $arrayPermisosStringsCollection = $this->getPermisosStrings($rol->getPermisos());
            $arrayPermisosStrings = $arrayPermisosStringsCollection;
            $this->setSession('arraypermisosString count', $arrayPermisosStrings ); 
            return $arrayPermisosStrings;
        }else{
            //To do; throw RolNotFoundException
            //return 'id null';
            $this->setSession('debug2', 'got rol null');
            return null;
        }
    }

    /**
    * @param array $permAuts
    * @return array
    */
    public function getPermisosStrings($permAuts){
        $stringsArray = new ArrayCollection();
        if ($this->permissionsMap!=null){
            foreach ($permAuts as $pa){
                if (  $this->permissionsMap->containsKey( $pa->getId() )  ){
                    $stringsArray->add(  $this->permissionsMap->get( $pa->getId() )  );
                }
            }
        }else{
        	$this->setSession( 'error','permisos map is null');	
            //To do: throw PermisoAutorizacionMapNullException;
        }
        return $stringsArray->toArray();
    }


    /**
     * 
     * @param string $q
     * @return string
     */
    public function encryptIt( $q ) {
        $cryptKey = 'qJB0rGtIn5UB1xG03efyCp';
        $qEncoded = base64_encode( mcrypt_encrypt( MCRYPT_RIJNDAEL_256, md5( $cryptKey ), $q, MCRYPT_MODE_CBC, md5( md5( $cryptKey ) ) ) );
        return( $qEncoded );
    }

    /**
     * 
     * @param string $q
     * @return string
     */
    public function decryptIt( $q ) {
        $cryptKey  = 'qJB0rGtIn5UB1xG03efyCp';
        $qDecoded  = rtrim( mcrypt_decrypt( MCRYPT_RIJNDAEL_256, md5( $cryptKey ), base64_decode( $q ), MCRYPT_MODE_CBC, md5( md5( $cryptKey ) ) ), "\0");
        return( $qDecoded );
    }


    public function getMainMenu(Request $request) //,SessionManager $sessionmanager)
    {
		$menu = $this->factory->createItem('root');
		$menu -> setChildrenAttributes(array ('class' => 'nav menuprincipal'));
		try{
			if (  ( $this->userIsLogged() ) && ( $this->pageHasMenu($request->get('_route')) )  ){
				$this->setSession('firstPass', 'no');
				if ($this->session->has('permisos')){
	
					if ($this->isGranted('VER_INCIDENTES') == true){  
						$menu->addChild('Incidentes', array(
															'route' => 'incidentes_listar', 
															'attributes' => array('id' => 'incidentes')
															)
										);
					}else{
						$this->setSession( 'isGrantedIncidentes returned: ','false');
					}
	
					if ($this->isGranted('VER_CONFIGURACION') == true){  
						$menu->addChild('Configuración', array('route' => 'chompsgi_inicio',
																'attributes' => array('id' => 'configuracion')
																)
	
										);
					}
	
					if ($this->isGranted('VER_REPORTES')  == true){
						$menu->addChild('Reportes', array('route' => 'reportes_inicio',
															'attributes' => array('id' => 'reportes',
                                                                                  'dropdown' => true,
                                                                                  'class' => 'dropdown',
                                                                                  'role'=>'menu')
														)
										);
                        $menu['Reportes']->setChildrenAttributes(array ('class' => 'dropdown-menu'));
                        $menu['Reportes']->addChild ('Horas por Cuenta Analítica', array('route' => 'reportes_hsEmpresa'));
                        $menu['Reportes']->addChild ('Horas por Resp. Soporte', array('route' => 'reportes_hsRespSop'));
                        $menu['Reportes']->addChild ('Incidentes Cerrados', array('route' => 'reportes_incCerr'));
                    /*   
                        $menu->addChild('User', array('label' => 'Hi visitor'))
                            ->setAttribute('dropdown', true)
                            ->setAttribute('icon', 'icon-user');
                 
                        $menu['User']->addChild('Edit profile', array('route' => 'acme_hello_profile'))
                            ->setAttribute('icon', 'icon-edit');
 
                         path('reportes_hsEmpresa') }}">Reporte de Horas por Cuenta Anal&iacute;tica</a></div>
<div><a href="{{ path('reportes_hsRespSop') }}">Reporte de Horas por Responsable Soporte</a></div>
<div><a href="{{ path('reportes_incCerr') }
                        */						
					}
	
/*					if ($this->isGranted('VER_SEGURIDAD')  == true){
						$menu->addChild('Seguridad', array('route' => 'seguridad',
															'attributes' => array('id' => 'seguridad')
	
															)
										);
					}
*/				   
				}
			} 
		}catch(LDAPErrorException $e){
			$this->addFlash('msgWarn','LDAP Usuario o Password Incorrecto');
			$this->closeSession();
		}catch(InexistentUserException $e){
			$this->addFlash('msgWarn','Usuario inexistente');
			$this->closeSession();
		}catch(IncorrectPasswordException $e){
			$this->addFlash('msgError','La contraseña es incorrecta, por favor inténtelo de nuevo.');
			$this->closeSession();
		}catch(InexistentEmpresaException $e){
			$this->addFlash('msgError','Su empresa ya no pertenece al sistema. Comuniquese con su administrador.');
			$this->closeSession();
		}catch(InactiveUserException $e){
			$this->setSession('firstPass', 'si');
			$this->closeSession();
			$this->addFlash('msgInfo','El usuario se encuentra inactivo. Por favor contacte a su administrador.');
		}catch(LockedUserException $e){
			$this->setSession('firstPass', 'si');
			$this->closeSession();
			$this->addFlash('msgInfo','El usuario se encuentra bloqueado. Por favor contacte a su administrador.');
		}catch(DeletedUserException $e){
			$this->setSession('firstPass', 'si');
			$this->closeSession();
			$this->addFlash('msgWarn','El usuario fue eliminado. Por favor contacte a su administrador.');
		}

		return $menu;
       
    }

	public function getLeftMenu(Request $request) //,SessionManager $sessionmanager)
    {
		$menu = $this->factory->createItem('root');
		$menu -> setChildrenAttributes(array ('class' => 'nav nav-tabs'));

    	if (  ( $this->userIsLogged() ) && ( $this->pageHasLeftMenu($request->get('_route')) )  ){
            if ($this->session->has('permisos')){
                
                $menu->addChild('ABM', array( 'attributes' => array ('class' => 'nav-header')
                                            )
                                );
            	
                if ($this->isGranted('VER_EMPRESA') == true){  
	                $menu->addChild('Empresas', array(
	                                                    'route' => 'empresa_listar', 
	                                                    'attributes' => array('id' => 'empresas')
	                                                    )
                                	);
				}

				if ($this->isGranted('VER_USUARIO') == true){  
	                $menu->addChild('Usuarios', array('route' => 'usuario_listar',
	                                                        'attributes' => array('id' => 'usuarios')
	                                                        )

	                                );
	            }

                if ($this->isGranted('VER_ESTADO') == true){  
                    $menu->addChild('Estados', array('route' => 'estado_listar',
                                                            'attributes' => array('id' => 'estados')
                                                            )
 
                                    );
                }

				if ($this->isGranted('VER_GRUPOSOPORTE')  == true){
	                $menu->addChild('Grupos de Soporte', array('route' => 'gruposoporte_listar',
	                                                    'attributes' => array('id' => 'grupos')
	                                                )
	                                );
				}
                
	            if ($this->isGranted('VER_CUENTAANALITICA')  == true){
	                $menu->addChild('Cuentas Analíticas', array('route' => 'cuentaAnalitica_listar',
	                                                    'attributes' => array('id' => 'cuentas')
	                                                )
	                                );
				}

                if ($this->isGranted('VER_WORKFLOW') == true){  
                    $menu->addChild('Workflows', array('route' => 'workflow_listar',
                                                            'attributes' => array('id' => 'workflows')
                                                            )
 
                                    );
                }

				if ($this->isGranted('VER_PRIORIDAD')  == true){
	                $menu->addChild('Definición de SLA', array('route' => 'prioridad_listar',
	                                                    'attributes' => array('id' => 'sla')
	                                                )
	                                );
				}
                if ($this->isGranted('VER_SEGURIDAD') == true){  
                    $menu->addChild('Seguridad', array('route' => 'seguridad_clave',
                                                            'attributes' => array('id' => 'seguridad')
                                                            )
 
                                    );
                }
            }
		} 
		return $menu;
       
    }
    

}

function encryptIt( $q ) {
    $cryptKey = 'qJB0rGtIn5UB1xG03efyCp';
    $qEncoded = base64_encode( mcrypt_encrypt( MCRYPT_RIJNDAEL_256, md5( $cryptKey ), $q, MCRYPT_MODE_CBC, md5( md5( $cryptKey ) ) ) );
    return( $qEncoded );
}


function decryptIt( $q ) {
    $cryptKey  = 'qJB0rGtIn5UB1xG03efyCp';
    $qDecoded  = rtrim( mcrypt_decrypt( MCRYPT_RIJNDAEL_256, md5( $cryptKey ), base64_decode( $q ), MCRYPT_MODE_CBC, md5( md5( $cryptKey ) ) ), "\0");
    return( $qDecoded );
}

